/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package rules;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import types.ColoringInfo;
import types.ISudokuMatrix;
import utils.RuleHelper;

/**
 *
 * @author ali
 */
public class QuadratTwoFreeCol implements Rule{

    int quadrat = 0;

     Collection checkedBlocks = new HashSet();
    Collection checkedCols = new HashSet();
    Collection checkedRows =new HashSet();

    public String getName() {
        return QuadratTwoFreeCol.class.getSimpleName();
    }

    public String getPicName() {
        return "Betrachte Block. Wenn höchstens 2 leere Felder vorhanden sind, betrachte dann \nSpalte und schließ aus. Die zwei leeren" +
               "Felder dürfen nicht in der gleichen Spalte sein.";
               
    }

    public boolean isApplicable(int x, int y, ISudokuMatrix matrix) {
        System.out.println("Trying to apply rule "+ this.getName()+ " for "+x+","+y);

        try {
            this.setQuadrat(x, y);
            Collection missedDigits = RuleHelper.getMissingdigitsInQuadratOrColOrRow(RuleHelper.getDigitsSameQuadrat(x, y, matrix));
            if (missedDigits.size() > 2)
                return false;
            
            
            if (!RuleHelper.zerosInTheSameColSameQuadratByAllowedNumber(x, y, matrix, 1))
                return false;
            
            int[] a = RuleHelper.getDigistsSameCol(y, matrix);
            
            Iterator iter = missedDigits.iterator();
            while (iter.hasNext())
            {
                int digit = (Integer)iter.next();
                if (RuleHelper.arrayIncludesdigit (a,digit)==false)
                {
                    this.checkedCols.add(y);
                    System.out.println("\tRule applicable");
                    return true;
                }
            }
            

        } catch (Exception ex) {
            Logger.getLogger(QuadratTwoFreeCol.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    /**
     *  Liefert das Kosten der Anwendung des Regels
     *  Kosten für Betrachtung des Quadrat selbst = 1
     *  Kosten für Betrachtung des direkt-benachbarten Quadrat = 2
     *  Kosten für Betrachtung des indirekt-benachbarten  (Nachbar des Nachbars)Quadrat = 3
     *  wenn mehrere artefakte gleichzeitig betrachtet werden müssen z.B. ein Quadrat und eine spalte dann
     *  kosten = (kosten (Quadrat) + kosten (Spalte))*Anzahl der Artefakte
     * +++++++++++++
     *  + 1 + 2 + 3 +
     *  +++++++++++++
     *  + 4 + 5 + 6 +
     *  +++++++++++++
     *  + 7 + 8 + 9 +
     *  +++++++++++++
     * @param QuadratNumber
     * @return
     */
    public int getWeight(int QuadratNumber) {

        if (QuadratNumber==4 || QuadratNumber==5 || QuadratNumber==6)
        {
            //(1+5)*2
            return 12;
        }
        else
            // (1+6)*2
            return 14;
    }


public int compareTo(Rule o) {
        if (this.getWeight(this.getQuadrat())<o.getWeight(o.getQuadrat()))
            return -1;
        else if (this.getWeight(this.getQuadrat())>o.getWeight(o.getQuadrat()))
            return 1;
        else
            return 0;
    }

    public void setQuadrat(int x, int y) throws Exception {

            this.quadrat = RuleHelper.calculateQuadratNumber(x, y);

    }

    public int getQuadrat() {
       return this.quadrat;
    }

    public ColoringInfo getCheckedUnits(int x, int y, ISudokuMatrix matrix) {
        ColoringInfo ci = new ColoringInfo();

        ci.setBlocks(this.checkedBlocks);
        ci.setColums(this.checkedCols);
        ci.setRows(this.checkedRows);

        return ci;
    }
}
